/**
 *  Copyright (C) 2006 zhangbo (freeeob@gmail.com)
 *
 *  This product is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *  (at your option) any later version.
 * 
 *  This product is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 *
 *  author:zhangbo
 *  Email:jsjava@gmail.com
 */
 
 /**  The SplineInterpolator class references to org.apache.commons.math.analysis.SplineInterpolator */
 
function SplineInterpolator(){
	this.jsjava_class="jsorg.apache.commons.math.analysis.SplineInterpolator";
}

/**
 * Computes an interpolating function for the data set.
 * @param arrx the arguments for the varerpolation povars
 * @param arry the values for the varerpolation povars
 */
SplineInterpolator.prototype.interpolate=function(arrx,arry){
	if (arrx.length != arry.length) {
            throw new IllegalArgumentException(IllegalArgumentException.ERROR,"Dataset arrays must have same length.");
        }
        
        if (arrx.length < 3) {
            throw new IllegalArgumentException
                (IllegalArgumentException.ERROR,"At least 3 datapovars are required to compute a spline varerpolant");
        }
        
        var n = arrx.length - 1;   
        
        for (var i = 0; i < n; i++) {
            if (arrx[i]  >= arrx[i + 1]) {
                throw new IllegalArgumentException(IllegalArgumentException.ERROR,"Dataset arrx values must be strictly increasing.");
            }
        }
        
        var h = new Array(n);
        for (var i = 0; i < n; i++) {
            h[i] = arrx[i + 1] - arrx[i];
        }
        
        var mu = new Array(n);
        var z = new Array(n + 1);
        mu[0] = 0;
        z[0] = 0;
        var g = 0;
        for (var i = 1; i < n; i++) {
            g = 2 * (arrx[i+1]  - arrx[i - 1]) - h[i - 1] * mu[i -1];
            mu[i] = h[i] / g;
            z[i] = (3 * (arry[i + 1] * h[i - 1] - arry[i] * (arrx[i + 1] - arrx[i - 1])+ arry[i - 1] * h[i]) /
                    (h[i - 1] * h[i]) - h[i - 1] * z[i - 1]) / g;
        }
       
        var b = new Array(n);
        var c = new Array(n+1);
        var d = new Array(n);
        
        z[n] = 0;
        c[n] = 0;
        
        for (var j = n -1; j >=0; j--) {
            c[j] = z[j] - mu[j] * c[j + 1];
            b[j] = (arry[j + 1] - arry[j]) / h[j] - h[j] * (c[j + 1] + 2 * c[j]) / 3;
            d[j] = (c[j + 1] - c[j]) / (3 * h[j]);
        }
        
        var polynomials = new Array(n);
        var coefficients = new Array(4);
        for (var i = 0; i < n; i++) {
            coefficients[0] = arry[i];
            coefficients[1] = b[i];
            coefficients[2] = c[i];
            coefficients[3] = d[i];
            polynomials[i] = new PolynomialFunction(coefficients);
        }
        
        return new PolynomialSplineFunction(arrx, polynomials);
};